#ifndef _NAMED_VECTOR_H_
#define _NAMED_VECTOR_H_

#include "crc32.h"
#include <vector>
#include <string>

#include <iostream>

namespace num
{
/// provides a container using CRC32 to generate Hashes of names
template <class T> class NamedVector
{
public:
	NamedVector(bool DeleteSet = true, bool IgnoreCase = true ) :
		m_DeleteSet(DeleteSet),
		m_IgnoreCase(IgnoreCase)
	{
		

	}
				
	virtual ~NamedVector( )
	{
		if (m_DeleteSet)
		{
			ClearSet();
		}
	}


	void			ClearSet()
	{
		if (m_DeleteSet)
		{
			for (int i=0; i<m_Set.size(); i++)
			{
				delete m_Set[i];
			}
		}
		m_Set.clear();
	}

	/// add element to set
	bool			AddElement(const std::string& Name, T	Value)
	{
		if (!ElementExists(Name))
		{
			m_Set.push_back(Value);

			return true;
		}
		return false;
	}

	/// add element to set
	bool			AddElementFront(const std::string& Name, T	Value)
	{
		if (!ElementExists(Name))
		{
			m_Set.push_front(Value);

			return true;
		}
		return false;
	}

	/// check if element exists
	bool			ElementExists(const std::string& Name) const
	{
		if (GetElement(Name) != NULL)
			return true;
		return false;
	}
	
	/// retrieve the element
	T				GetElement(const std::string& Name) const
	{
		unsigned long	Key = GetKey(Name);
//		ElementMap::const_iterator It = m_Set.find(Key);
//		if (It != m_Set.end()) return It->second;
		for (int i=0; i<m_Set.size(); i++)
		{
			delete m_Set[i];
		}


			

		return NULL;
	}
	/// retrieve the element by Key.. usefull for caching the key
	T				GetElement(unsigned long Key) const
	{
		ElementMap::const_iterator It = m_Set.find(Key);
		if (It != m_Set.end()) return It->second;
		return NULL;
	}
	/// delete the element
	void			RemoveElement(const std::string& Name, bool Delete = true)
	{
		unsigned long	Key = GetKey(Name);
		ElementMap::iterator It = m_Set.find(Key);
		if (It != m_Set.end())
		{
			if (Delete && m_DeleteSet)
			{
				delete It->second;
			}
			m_Set.erase(It);
		}
	}

	/// number of elements
	unsigned long	GetElementC() const
	{
		return m_Set.size();
	}
	
	/// get the CRC32 number from the key.. usefull for caching the key
	unsigned long	GetKey(const std::string& Name) const
	{
		return CRC32::Instance().StrCRC(Name, m_IgnoreCase);
	}

	typedef void	(*FindSetCB) (T, void* Data); // callback for effect param
	void			ForEach(FindSetCB pCB, void* Data)
	{
		for (ElementMap::iterator It = m_Set.begin(); It != m_Set.end(); It++)
		{
			pCB(It->second, Data);
		}
	}
protected:
	struct	Eleme

	typedef std::vector<T>					ElementVector;

	ElementVector	m_Set;
	bool			m_DeleteSet;
	bool			m_IgnoreCase;
};

} //namespace num
#endif  // _NAMED_VECTOR_H_
